const ValueType = <const>[
  'Null',
  'Undefined',
  'Object',
  'Array',
  'String',
  'Number',
  'Boolean',
  'Function',
  'RegExp',
  'Json',
  'Date',
  'Symbol',
];

type IValueType = (typeof ValueType)[number];

/**
 * 类型判断
 * @param {Any} value 需要判断的值
 * @param {String} type 值的类型
 * @return {String|Boolean}
 */
export const checkTypeof = (value: any, type?: IValueType) => {
  let typeStr = undefined;

  if (
    value &&
    'function' == typeof Symbol &&
    value.constructor === Symbol &&
    value !== Symbol.prototype
  ) {
    typeStr = 'symbol';
  } else {
    typeStr = Object.prototype.toString.call(value).slice(8, -1);
  }

  // 如果传入有type，则当作类型判断结果返回
  if (type) {
    return typeStr === type.substring(0, 1).toUpperCase() + type.substring(1);
  }

  return typeStr.toLowerCase();
};

/**
 * cached缓存操作函数
 */
function cached(fn: Function) {
  const cache = Object.create(null);
  return function cachedFn(str: string) {
    const hit = cache[str];
    return hit || (cache[str] = fn(str));
  };
}

/**
 * 驼峰化函数
 * @param str
 * @returns
 */
export const camelize = cached((str: string) => {
  return str.replace(/-(\w)/g, (_, c) => (c ? c.toUpperCase() : ''));
});

/**
 * 字符单词首字母转大写
 * @param value
 * @returns
 */
export const ucfirst = (value: string) => {
  if (!!value) {
    return value.charAt(0).toUpperCase() + value.slice(1);
  }

  return value;
};

/**
 * 字符每个单词首字母转大写
 * @param value
 * @returns
 */
export const ucwords = (value: string) => {
  // 1.charAt（下标）：返回某个下标所对应的字符， 若没有这个字符则返回一个空字符
  // 2.join(' ')把数组按照规定的字符连成字符串，如join（' '）括号里面是空，那么就把数组每一项的按照空字符连接成字符串
  return value
    .toLowerCase()
    .split(/\s+/)
    .map((item) => {
      return item.replace(item.charAt(0), item.charAt(0).toUpperCase());
    })
    .join(' ');
};

/**
 * 去两边空格，速度最快
 * @param value
 * @returns
 */
export const trim = (value: string) => {
  if (!value) {
    return '';
  }

  if (String.prototype.trim) {
    return String.prototype.trim.call(value);
  }
  // value.replace(/^\s+|\s+$/g, '');

  var whitespace =
    ' \n\r\t\f\x0b\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000\ufeff';
  for (var i = 0; i < value.length; i++) {
    if (whitespace.indexOf(value.charAt(i)) === -1) {
      value = value.substring(i);
      break;
    }
  }
  for (i = value.length - 1; i >= 0; i--) {
    if (whitespace.indexOf(value.charAt(i)) === -1) {
      value = value.substring(0, i + 1);
      break;
    }
  }
  return whitespace.indexOf(value.charAt(0)) === -1 ? value : '';
};

/**
 * 删除左边的空格
 * @param value
 * @returns
 */
export const trimLeft = (value: string) => {
  return !value
    ? ''
    : String.prototype.trimStart
      ? String.prototype.trimStart.call(value)
      : value.replace(/(^[\s\n\r\t\xa0\u3000]*)/g, '');
};

/**
 * 删除右边的空格
 * @param value
 * @returns
 */
export const trimRight = (value: string) => {
  return !value
    ? ''
    : String.prototype.trimEnd
      ? String.prototype.trimEnd.call(value)
      : value.replace(/([\u3000\xa0\s\n\r\t]*$)/g, '');
};
